package com.yunke.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yunke.entity.YunkeDazi;
import com.yunke.mapper.YunkeDaziMapper;
import com.yunke.util.YunkeDaziStatusUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * 云科搭子管理定时任务
 * 
 * @author yunke
 * @since 2024-01-01
 */
@Slf4j
@Component
public class YunkeDaziScheduleTask {

    @Autowired
    private YunkeDaziMapper daziMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // Redis缓存键前缀
    private static final String CACHE_DAZI_DETAIL_KEY = "yunke:dazi:detail:";
    private static final String CACHE_VIEW_COUNT_KEY = "yunke:dazi:view:";

    /**
     * 每小时检查一次搭子状态并自动更新
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void updateExpiredDazi() {
        log.info("开始执行搭子状态自动更新任务");
        
        try {
            long currentTime = System.currentTimeMillis();
            
            // 查找已过期但状态仍为已发布的搭子
            LambdaQueryWrapper<YunkeDazi> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(YunkeDazi::getStatus, 1) // 已发布
                   .eq(YunkeDazi::getAuditStatus, 1) // 审核通过
                   .lt(YunkeDazi::getActivityTime, currentTime); // 活动时间已过
            
            List<YunkeDazi> expiredDaziList = daziMapper.selectList(wrapper);
            
            if (!expiredDaziList.isEmpty()) {
                // 批量更新为已结束状态
                LambdaUpdateWrapper<YunkeDazi> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(YunkeDazi::getStatus, 1)
                           .eq(YunkeDazi::getAuditStatus, 1)
                           .lt(YunkeDazi::getActivityTime, currentTime)
                           .set(YunkeDazi::getStatus, 2) // 已结束
                           .set(YunkeDazi::getUpdateTime, currentTime);
                
                int updateCount = daziMapper.update(null, updateWrapper);
                log.info("自动更新过期搭子状态完成，更新数量: {}", updateCount);
                
                // 清除相关缓存
                for (YunkeDazi dazi : expiredDaziList) {
                    redisTemplate.delete(CACHE_DAZI_DETAIL_KEY + dazi.getId());
                }
            }
            
            // 处理置顶过期的搭子
            updateExpiredTopDazi(currentTime);
            
        } catch (Exception e) {
            log.error("搭子状态自动更新任务执行失败", e);
        }
    }

    /**
     * 更新置顶过期的搭子
     */
    private void updateExpiredTopDazi(long currentTime) {
        try {
            // 查找置顶已过期的搭子
            LambdaQueryWrapper<YunkeDazi> topWrapper = new LambdaQueryWrapper<>();
            topWrapper.eq(YunkeDazi::getIsTop, 1)
                     .isNotNull(YunkeDazi::getTopEndTime)
                     .lt(YunkeDazi::getTopEndTime, currentTime);
            
            List<YunkeDazi> expiredTopList = daziMapper.selectList(topWrapper);
            
            if (!expiredTopList.isEmpty()) {
                // 批量取消置顶
                LambdaUpdateWrapper<YunkeDazi> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(YunkeDazi::getIsTop, 1)
                           .isNotNull(YunkeDazi::getTopEndTime)
                           .lt(YunkeDazi::getTopEndTime, currentTime)
                           .set(YunkeDazi::getIsTop, 0)
                           .set(YunkeDazi::getTopTime, (Long) null)
                           .set(YunkeDazi::getTopEndTime, (Long) null)
                           .set(YunkeDazi::getUpdateTime, currentTime);
                
                int updateCount = daziMapper.update(null, updateWrapper);
                log.info("自动取消过期置顶完成，更新数量: {}", updateCount);
                
                // 清除相关缓存
                for (YunkeDazi dazi : expiredTopList) {
                    redisTemplate.delete(CACHE_DAZI_DETAIL_KEY + dazi.getId());
                }
            }
        } catch (Exception e) {
            log.error("处理置顶过期搭子失败", e);
        }
    }

    /**
     * 每6小时同步一次Redis浏览量数据到数据库
     */
    @Scheduled(cron = "0 0 */6 * * ?")
    public void syncViewCountToDatabase() {
        log.info("开始执行浏览量数据同步任务");
        
        try {
            Set<String> viewKeys = redisTemplate.keys(CACHE_VIEW_COUNT_KEY + "*");
            if (viewKeys == null || viewKeys.isEmpty()) {
                log.info("没有浏览量数据需要同步");
                return;
            }
            
            int syncCount = 0;
            for (String key : viewKeys) {
                try {
                    // 解析搭子ID
                    String daziIdStr = key.substring(CACHE_VIEW_COUNT_KEY.length());
                    Long daziId = Long.parseLong(daziIdStr);
                    
                    // 获取Redis中的浏览量
                    Object viewCountObj = redisTemplate.opsForValue().get(key);
                    if (viewCountObj != null) {
                        Integer viewCount = (Integer) viewCountObj;
                        
                        // 更新数据库
                        LambdaUpdateWrapper<YunkeDazi> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(YunkeDazi::getId, daziId)
                                   .setSql("view_count = view_count + " + viewCount);
                        
                        int updateResult = daziMapper.update(null, updateWrapper);
                        if (updateResult > 0) {
                            // 删除Redis中的缓存
                            redisTemplate.delete(key);
                            syncCount++;
                        }
                    }
                } catch (Exception e) {
                    log.warn("同步单个浏览量数据失败: key={}", key, e);
                }
            }
            
            log.info("浏览量数据同步完成，同步数量: {}", syncCount);
        } catch (Exception e) {
            log.error("浏览量数据同步任务执行失败", e);
        }
    }

    /**
     * 每天凌晨2点清理过期缓存
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void cleanExpiredCache() {
        log.info("开始执行过期缓存清理任务");
        
        try {
            // 清理搭子详情缓存（检查搭子是否已删除）
            Set<String> detailKeys = redisTemplate.keys(CACHE_DAZI_DETAIL_KEY + "*");
            if (detailKeys != null) {
                int cleanCount = 0;
                for (String key : detailKeys) {
                    try {
                        String daziIdStr = key.substring(CACHE_DAZI_DETAIL_KEY.length());
                        Long daziId = Long.parseLong(daziIdStr);
                        
                        // 检查搭子是否存在或已删除
                        YunkeDazi dazi = daziMapper.selectById(daziId);
                        if (dazi == null || dazi.getStatus() == 4) { // 已删除
                            redisTemplate.delete(key);
                            cleanCount++;
                        }
                    } catch (Exception e) {
                        log.warn("清理单个缓存失败: key={}", key, e);
                    }
                }
                log.info("清理过期搭子详情缓存完成，清理数量: {}", cleanCount);
            }
            
        } catch (Exception e) {
            log.error("过期缓存清理任务执行失败", e);
        }
    }

    /**
     * 每天统计搭子活跃度数据（可扩展用于数据分析）
     */
    @Scheduled(cron = "0 30 1 * * ?")
    public void statisticsDaziActivity() {
        log.info("开始执行搭子活跃度统计任务");
        
        try {
            long currentTime = System.currentTimeMillis();
            long dayStartTime = currentTime - (24 * 60 * 60 * 1000); // 24小时前
            
            // 统计今日新发布的搭子数量
            LambdaQueryWrapper<YunkeDazi> newDaziWrapper = new LambdaQueryWrapper<>();
            newDaziWrapper.eq(YunkeDazi::getStatus, 1)
                         .ge(YunkeDazi::getPublishTime, dayStartTime)
                         .le(YunkeDazi::getPublishTime, currentTime);
            long newDaziCount = daziMapper.selectCount(newDaziWrapper);
            
            // 统计今日结束的搭子数量
            LambdaQueryWrapper<YunkeDazi> finishedWrapper = new LambdaQueryWrapper<>();
            finishedWrapper.eq(YunkeDazi::getStatus, 2)
                          .ge(YunkeDazi::getActivityTime, dayStartTime)
                          .le(YunkeDazi::getActivityTime, currentTime);
            long finishedCount = daziMapper.selectCount(finishedWrapper);
            
            // 统计活跃搭子数量（有参与者的搭子）
            LambdaQueryWrapper<YunkeDazi> activeWrapper = new LambdaQueryWrapper<>();
            activeWrapper.eq(YunkeDazi::getStatus, 1)
                        .gt(YunkeDazi::getJoinedPeople, 1);
            long activeCount = daziMapper.selectCount(activeWrapper);
            
            log.info("今日搭子活跃度统计 - 新发布: {}, 已结束: {}, 活跃中: {}", 
                    newDaziCount, finishedCount, activeCount);
            
            // TODO: 可以将统计数据保存到统计表或发送到监控系统
            
        } catch (Exception e) {
            log.error("搭子活跃度统计任务执行失败", e);
        }
    }
} 